﻿// ***********************************************************************
// Assembly         : TfsDispatcher
// Author           : Eric Cocquerez
// Created          : 07-26-2014
//
// Last Modified By : Eric Cocquerez
// Last Modified On : 07-27-2014
// ***********************************************************************
// <copyright file="ServerDispatcher.cs" company="Personnel">
//     Copyright (c) Personnel. All rights reserved.
// </copyright>
// <summary></summary>
// ***********************************************************************

namespace TfsDispatcher
{
#region Using
	using System;
	using System.Configuration;
	using System.Diagnostics;
	using System.IO;
	using System.Messaging;

	using DispatcherModel;

	using Microsoft.TeamFoundation.Build.Server;
	using Microsoft.TeamFoundation.Common;
	using Microsoft.TeamFoundation.Framework.Server;
#endregion
    /// <summary>
    /// Class ServerDispatcher.
    /// </summary>
    public class ServerDispatcher : ISubscriber
    {
		private System.Diagnostics.EventLog eventLogDispatcher;

		/// <summary>
		/// Initializes a new instance of the <see cref="ServerDispatcher"/> class, using
		/// the default config file name
		/// </summary>
	    public ServerDispatcher()
	    {
		    GetConfiguration.InitializeConfiguration();
			if (GetConfiguration.IsLog)
			{
				this.eventLogDispatcher = new EventLog();
				if (!EventLog.SourceExists("TfsDispatcher"))
				{
					EventLog.CreateEventSource("TfsDispatcher", "TfsDispatcherLog");
				}
				this.eventLogDispatcher.Source = "TfsDispatcher";
				this.eventLogDispatcher.Log = "TfsDispatcherLog";
			}
	    }

        /// <summary>
        /// Gets the name.
        /// </summary>
        /// <value>The name of this Dispatcher</value>
        public string Name
        {
            get { return "BuildQualityServerDispatcher"; }
        }

        /// <summary>
        /// Gets the priority.
        /// </summary>
        /// <value>Always return SubscriberPriority.Normal</value>
        public SubscriberPriority Priority
        {
            get
            {
                return SubscriberPriority.Normal;
            }
        }

        /// <summary>
        /// Subscribed the types.
        /// </summary>
        /// <returns>Type[] of event we subscribed</returns>
        public Type[] SubscribedTypes()
        {
            return new Type[1] { typeof(BuildQualityChangedNotificationEvent) };
        }

        /// <summary>
        /// Processes the event.
        /// </summary>
        /// <param name="requestContext">The request context.</param>
        /// <param name="notificationType">Type of the notification.</param>
        /// <param name="notificationEventArgs">The notification event arguments.</param>
        /// <param name="statusCode">The status code.</param>
        /// <param name="statusMessage">The status message.</param>
        /// <param name="properties">The properties.</param>
        /// <returns>return the EventNotificationStatus.ActionApproved</returns>
        public EventNotificationStatus ProcessEvent(
            TeamFoundationRequestContext requestContext,
            NotificationType notificationType,
            object notificationEventArgs,
            out int statusCode,
            out string statusMessage,
            out ExceptionPropertyCollection properties)
        {
			var address = string.Empty;
			var port = string.Empty;
			statusCode = 0;
            properties = null;
            statusMessage = string.Empty;
	        if (GetConfiguration.IsLog)
	        {
				this.eventLogDispatcher.WriteEntry("Receiving new notification");
	        }

			if (notificationType != NotificationType.Notification)
            {
				if (GetConfiguration.IsLog)
				{
					this.eventLogDispatcher.WriteEntry("Not a notification type, exiting");
				}
				return EventNotificationStatus.ActionApproved;
            }

            var buildQuality = notificationEventArgs as BuildQualityChangedNotificationEvent;
            if (buildQuality == null)
            {
				if (GetConfiguration.IsLog)
				{
					this.eventLogDispatcher.WriteEntry("Not a BuildQualityChangedNotificationEvent, exiting");
				}
				return EventNotificationStatus.ActionApproved;
            }

	        if (GetConfiguration.IsDebug)
	        {
		        Debugger.Launch();
	        }

	        var buildQualityValues = new BuildQualityValues();
	        buildQualityValues.NewValue = buildQuality.NewValue;
	        buildQualityValues.OldValue = buildQuality.OldValue;
	        buildQualityValues.TeamProject = buildQuality.Build.TeamProject;
	        buildQualityValues.BuildControllerUri = buildQuality.Build.BuildControllerUri;
	        buildQualityValues.BuildDefinitionName = buildQuality.Build.Definition.Name;
	        buildQualityValues.BuildDefinitionUri = buildQuality.Build.BuildDefinitionUri;
	        buildQualityValues.BuildNumber = buildQuality.Build.BuildNumber;
	        buildQualityValues.CompilationStatus = buildQuality.Build.CompilationStatus.ToString();
	        buildQualityValues.ContainerId = buildQuality.Build.ContainerId;
	        buildQualityValues.DropLocation = buildQuality.Build.DropLocation;
	        var addressProperty = GetConfiguration.MulticastAddress;
	        var portProperty = GetConfiguration.MulticastPort;
	        address = string.IsNullOrEmpty(addressProperty) ? "224.34.1.1" : addressProperty;
			port = string.IsNullOrEmpty(portProperty) ? "4151" : portProperty;
	        var addressMsmq = string.Format("formatname:multicast={0}:{1}", address, port);
	        using (var sender = new MessageQueue(addressMsmq))
	        {
		        sender.Formatter = new XmlMessageFormatter();
				sender.Send(buildQualityValues);
				if (GetConfiguration.IsLog)
				{
					this.eventLogDispatcher.WriteEntry("Message from project : " + buildQualityValues.TeamProject + " send to " + addressMsmq);
				}
	        }

            return EventNotificationStatus.ActionApproved;
        }
    }
}
